define("gallery/placeholders/3.0.2/placeholders-debug", [ "./utils-debug" ], function(require, exports, module) {
    require("./utils-debug");
    (function(global) {
        "use strict";
        var validTypes = [ "text", "search", "url", "tel", "email", "password", "number", "textarea" ], // The list of keycodes that are not allowed when the polyfill is configured to hide-on-input
        badKeys = [ // The following keys all cause the caret to jump to the end of the input value
        27, // Escape
        33, // Page up
        34, // Page down
        35, // End
        36, // Home
        // Arrow keys allow you to move the caret manually, which should be prevented when the placeholder is visible
        37, // Left
        38, // Up
        39, // Right
        40, // Down
        // The following keys allow you to modify the placeholder text by removing characters, which should be prevented when the placeholder is visible
        8, // Backspace
        46 ], // Styling variables
        placeholderStyleColor = "#ccc", placeholderClassName = "placeholdersjs", classNameRegExp = new RegExp("(?:^|\\s)" + placeholderClassName + "(?!\\S)"), // These will hold references to all elements that can be affected. NodeList objects are live, so we only need to get those references once
        inputs, textareas, // The various data-* attributes used by the polyfill
        ATTR_CURRENT_VAL = "data-placeholder-value", ATTR_ACTIVE = "data-placeholder-active", ATTR_INPUT_TYPE = "data-placeholder-type", ATTR_FORM_HANDLED = "data-placeholder-submit", ATTR_EVENTS_BOUND = "data-placeholder-bound", ATTR_OPTION_FOCUS = "data-placeholder-focus", ATTR_OPTION_LIVE = "data-placeholder-live", ATTR_MAXLENGTH = "data-placeholder-maxlength", // Various other variables used throughout the rest of the script
        test = document.createElement("input"), head = document.getElementsByTagName("head")[0], root = document.documentElement, Placeholders = global.Placeholders, Utils = Placeholders.Utils, hideOnInput, liveUpdates, keydownVal, styleElem, styleRules, placeholder, timer, form, elem, len, i;
        // No-op (used in place of public methods when native support is detected)
        function noop() {}
        // Avoid IE9 activeElement of death when an iframe is used.
        // More info:
        // http://bugs.jquery.com/ticket/13393
        // https://github.com/jquery/jquery/commit/85fc5878b3c6af73f42d61eedf73013e7faae408
        function safeActiveElement() {
            try {
                return document.activeElement;
            } catch (err) {}
        }
        // Hide the placeholder value on a single element. Returns true if the placeholder was hidden and false if it was not (because it wasn't visible in the first place)
        function hidePlaceholder(elem, keydownValue) {
            var type, maxLength, valueChanged = !!keydownValue && elem.value !== keydownValue, isPlaceholderValue = elem.value === elem.getAttribute(ATTR_CURRENT_VAL);
            if ((valueChanged || isPlaceholderValue) && elem.getAttribute(ATTR_ACTIVE) === "true") {
                elem.removeAttribute(ATTR_ACTIVE);
                elem.value = elem.value.replace(elem.getAttribute(ATTR_CURRENT_VAL), "");
                elem.className = elem.className.replace(classNameRegExp, "");
                // Restore the maxlength value
                maxLength = elem.getAttribute(ATTR_MAXLENGTH);
                if (parseInt(maxLength, 10) >= 0) {
                    // Old FF returns -1 if attribute not set (see GH-56)
                    elem.setAttribute("maxLength", maxLength);
                    elem.removeAttribute(ATTR_MAXLENGTH);
                }
                // If the polyfill has changed the type of the element we need to change it back
                type = elem.getAttribute(ATTR_INPUT_TYPE);
                if (type) {
                    elem.type = type;
                }
                return true;
            }
            return false;
        }
        // Show the placeholder value on a single element. Returns true if the placeholder was shown and false if it was not (because it was already visible)
        function showPlaceholder(elem) {
            var type, maxLength, val = elem.getAttribute(ATTR_CURRENT_VAL);
            if (elem.value === "" && val) {
                elem.setAttribute(ATTR_ACTIVE, "true");
                elem.value = val;
                elem.className += " " + placeholderClassName;
                // Store and remove the maxlength value
                maxLength = elem.getAttribute(ATTR_MAXLENGTH);
                if (!maxLength) {
                    elem.setAttribute(ATTR_MAXLENGTH, elem.maxLength);
                    elem.removeAttribute("maxLength");
                }
                // If the type of element needs to change, change it (e.g. password inputs)
                type = elem.getAttribute(ATTR_INPUT_TYPE);
                if (type) {
                    elem.type = "text";
                } else if (elem.type === "password") {
                    if (Utils.changeType(elem, "text")) {
                        elem.setAttribute(ATTR_INPUT_TYPE, "password");
                    }
                }
                return true;
            }
            return false;
        }
        function handleElem(node, callback) {
            var handleInputsLength, handleTextareasLength, handleInputs, handleTextareas, elem, len, i;
            // Check if the passed in node is an input/textarea (in which case it can't have any affected descendants)
            if (node && node.getAttribute(ATTR_CURRENT_VAL)) {
                callback(node);
            } else {
                // If an element was passed in, get all affected descendants. Otherwise, get all affected elements in document
                handleInputs = node ? node.getElementsByTagName("input") : inputs;
                handleTextareas = node ? node.getElementsByTagName("textarea") : textareas;
                handleInputsLength = handleInputs ? handleInputs.length : 0;
                handleTextareasLength = handleTextareas ? handleTextareas.length : 0;
                // Run the callback for each element
                for (i = 0, len = handleInputsLength + handleTextareasLength; i < len; i++) {
                    elem = i < handleInputsLength ? handleInputs[i] : handleTextareas[i - handleInputsLength];
                    callback(elem);
                }
            }
        }
        // Return all affected elements to their normal state (remove placeholder value if present)
        function disablePlaceholders(node) {
            handleElem(node, hidePlaceholder);
        }
        // Show the placeholder value on all appropriate elements
        function enablePlaceholders(node) {
            handleElem(node, showPlaceholder);
        }
        // Returns a function that is used as a focus event handler
        function makeFocusHandler(elem) {
            return function() {
                // Only hide the placeholder value if the (default) hide-on-focus behaviour is enabled
                if (hideOnInput && elem.value === elem.getAttribute(ATTR_CURRENT_VAL) && elem.getAttribute(ATTR_ACTIVE) === "true") {
                    // Move the caret to the start of the input (this mimics the behaviour of all browsers that do not hide the placeholder on focus)
                    Utils.moveCaret(elem, 0);
                } else {
                    // Remove the placeholder
                    hidePlaceholder(elem);
                }
            };
        }
        // Returns a function that is used as a blur event handler
        function makeBlurHandler(elem) {
            return function() {
                showPlaceholder(elem);
            };
        }
        // Functions that are used as a event handlers when the hide-on-input behaviour has been activated - very basic implementation of the "input" event
        function makeKeydownHandler(elem) {
            return function(e) {
                keydownVal = elem.value;
                //Prevent the use of the arrow keys (try to keep the cursor before the placeholder)
                if (elem.getAttribute(ATTR_ACTIVE) === "true") {
                    if (keydownVal === elem.getAttribute(ATTR_CURRENT_VAL) && Utils.inArray(badKeys, e.keyCode)) {
                        if (e.preventDefault) {
                            e.preventDefault();
                        }
                        return false;
                    }
                }
            };
        }
        function makeKeyupHandler(elem) {
            return function() {
                hidePlaceholder(elem, keydownVal);
                // If the element is now empty we need to show the placeholder
                if (elem.value === "") {
                    elem.blur();
                    Utils.moveCaret(elem, 0);
                }
            };
        }
        function makeClickHandler(elem) {
            return function() {
                if (elem === safeActiveElement() && elem.value === elem.getAttribute(ATTR_CURRENT_VAL) && elem.getAttribute(ATTR_ACTIVE) === "true") {
                    Utils.moveCaret(elem, 0);
                }
            };
        }
        // Returns a function that is used as a submit event handler on form elements that have children affected by this polyfill
        function makeSubmitHandler(form) {
            return function() {
                // Turn off placeholders on all appropriate descendant elements
                disablePlaceholders(form);
            };
        }
        // Bind event handlers to an element that we need to affect with the polyfill
        function newElement(elem) {
            // If the element is part of a form, make sure the placeholder string is not submitted as a value
            if (elem.form) {
                form = elem.form;
                // If the type of the property is a string then we have a "form" attribute and need to get the real form
                if (typeof form === "string") {
                    form = document.getElementById(form);
                }
                // Set a flag on the form so we know it's been handled (forms can contain multiple inputs)
                if (!form.getAttribute(ATTR_FORM_HANDLED)) {
                    Utils.addEventListener(form, "submit", makeSubmitHandler(form));
                    form.setAttribute(ATTR_FORM_HANDLED, "true");
                }
            }
            // Bind event handlers to the element so we can hide/show the placeholder as appropriate
            Utils.addEventListener(elem, "focus", makeFocusHandler(elem));
            Utils.addEventListener(elem, "blur", makeBlurHandler(elem));
            // If the placeholder should hide on input rather than on focus we need additional event handlers
            if (hideOnInput) {
                Utils.addEventListener(elem, "keydown", makeKeydownHandler(elem));
                Utils.addEventListener(elem, "keyup", makeKeyupHandler(elem));
                Utils.addEventListener(elem, "click", makeClickHandler(elem));
            }
            // Remember that we've bound event handlers to this element
            elem.setAttribute(ATTR_EVENTS_BOUND, "true");
            elem.setAttribute(ATTR_CURRENT_VAL, placeholder);
            // If the element doesn't have a value and is not focussed, set it to the placeholder string
            if (hideOnInput || elem !== safeActiveElement()) {
                showPlaceholder(elem);
            }
        }
        Placeholders.nativeSupport = test.placeholder !== void 0;
        if (!Placeholders.nativeSupport) {
            // Get references to all the input and textarea elements currently in the DOM (live NodeList objects to we only need to do this once)
            inputs = document.getElementsByTagName("input");
            textareas = document.getElementsByTagName("textarea");
            // Get any settings declared as data-* attributes on the root element (currently the only options are whether to hide the placeholder on focus or input and whether to auto-update)
            hideOnInput = root.getAttribute(ATTR_OPTION_FOCUS) === "false";
            liveUpdates = root.getAttribute(ATTR_OPTION_LIVE) !== "false";
            // Create style element for placeholder styles (instead of directly setting style properties on elements - allows for better flexibility alongside user-defined styles)
            styleElem = document.createElement("style");
            styleElem.type = "text/css";
            // Create style rules as text node
            styleRules = document.createTextNode("." + placeholderClassName + " { color:" + placeholderStyleColor + "; }");
            // Append style rules to newly created stylesheet
            if (styleElem.styleSheet) {
                styleElem.styleSheet.cssText = styleRules.nodeValue;
            } else {
                styleElem.appendChild(styleRules);
            }
            // Prepend new style element to the head (before any existing stylesheets, so user-defined rules take precedence)
            head.insertBefore(styleElem, head.firstChild);
            // Set up the placeholders
            for (i = 0, len = inputs.length + textareas.length; i < len; i++) {
                elem = i < inputs.length ? inputs[i] : textareas[i - inputs.length];
                // Get the value of the placeholder attribute, if any. IE10 emulating IE7 fails with getAttribute, hence the use of the attributes node
                placeholder = elem.attributes.placeholder;
                if (placeholder) {
                    // IE returns an empty object instead of undefined if the attribute is not present
                    placeholder = placeholder.nodeValue;
                    // Only apply the polyfill if this element is of a type that supports placeholders, and has a placeholder attribute with a non-empty value
                    if (placeholder && Utils.inArray(validTypes, elem.type)) {
                        newElement(elem);
                    }
                }
            }
            // If enabled, the polyfill will repeatedly check for changed/added elements and apply to those as well
            timer = setInterval(function() {
                for (i = 0, len = inputs.length + textareas.length; i < len; i++) {
                    elem = i < inputs.length ? inputs[i] : textareas[i - inputs.length];
                    // Only apply the polyfill if this element is of a type that supports placeholders, and has a placeholder attribute with a non-empty value
                    placeholder = elem.attributes.placeholder;
                    if (placeholder) {
                        placeholder = placeholder.nodeValue;
                        if (placeholder && Utils.inArray(validTypes, elem.type)) {
                            // If the element hasn't had event handlers bound to it then add them
                            if (!elem.getAttribute(ATTR_EVENTS_BOUND)) {
                                newElement(elem);
                            }
                            // If the placeholder value has changed or not been initialised yet we need to update the display
                            if (placeholder !== elem.getAttribute(ATTR_CURRENT_VAL) || elem.type === "password" && !elem.getAttribute(ATTR_INPUT_TYPE)) {
                                // Attempt to change the type of password inputs (fails in IE < 9)
                                if (elem.type === "password" && !elem.getAttribute(ATTR_INPUT_TYPE) && Utils.changeType(elem, "text")) {
                                    elem.setAttribute(ATTR_INPUT_TYPE, "password");
                                }
                                // If the placeholder value has changed and the placeholder is currently on display we need to change it
                                if (elem.value === elem.getAttribute(ATTR_CURRENT_VAL)) {
                                    elem.value = placeholder;
                                }
                                // Keep a reference to the current placeholder value in case it changes via another script
                                elem.setAttribute(ATTR_CURRENT_VAL, placeholder);
                            }
                        }
                    } else if (elem.getAttribute(ATTR_ACTIVE)) {
                        hidePlaceholder(elem);
                        elem.removeAttribute(ATTR_CURRENT_VAL);
                    }
                }
                // If live updates are not enabled cancel the timer
                if (!liveUpdates) {
                    clearInterval(timer);
                }
            }, 100);
        }
        Utils.addEventListener(global, "beforeunload", function() {
            Placeholders.disable();
        });
        // Expose public methods
        Placeholders.disable = Placeholders.nativeSupport ? noop : disablePlaceholders;
        Placeholders.enable = Placeholders.nativeSupport ? noop : enablePlaceholders;
    })(this);
    module.exports = Placeholders;
    try {
        delete window.Placeholders;
    } catch (e) {
        window.Placeholders = null;
    }
});

define("gallery/placeholders/3.0.2/utils-debug", [], function(require, exports, module) {
    /* 
 * The MIT License
 *
 * Copyright (c) 2012 James Allardice
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), 
 * to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 
 * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
    // Defines the global Placeholders object along with various utility methods
    (function(global) {
        "use strict";
        // Cross-browser DOM event binding
        function addEventListener(elem, event, fn) {
            if (elem.addEventListener) {
                return elem.addEventListener(event, fn, false);
            }
            if (elem.attachEvent) {
                return elem.attachEvent("on" + event, fn);
            }
        }
        // Check whether an item is in an array (we don't use Array.prototype.indexOf so we don't clobber any existing polyfills - this is a really simple alternative)
        function inArray(arr, item) {
            var i, len;
            for (i = 0, len = arr.length; i < len; i++) {
                if (arr[i] === item) {
                    return true;
                }
            }
            return false;
        }
        // Move the caret to the index position specified. Assumes that the element has focus
        function moveCaret(elem, index) {
            var range;
            if (elem.createTextRange) {
                range = elem.createTextRange();
                range.move("character", index);
                range.select();
            } else if (elem.selectionStart) {
                elem.focus();
                elem.setSelectionRange(index, index);
            }
        }
        // Attempt to change the type property of an input element
        function changeType(elem, type) {
            try {
                elem.type = type;
                return true;
            } catch (e) {
                // You can't change input type in IE8 and below
                return false;
            }
        }
        // Expose public methods
        global.Placeholders = {
            Utils: {
                addEventListener: addEventListener,
                inArray: inArray,
                moveCaret: moveCaret,
                changeType: changeType
            }
        };
    })(this);
});
